﻿using System;
using System.Collections;
using System.Threading;

namespace WFIM.Framework.Parellel
{
  /// <include file='XMLCodeDocumentation.xml' path='documentation/item[@name="T_ParallelTaskManager"]/*' />
  public abstract class ParallelTaskManager
  {
    //-----------------------------------------------------------------------
    // FIELDS
    //-----------------------------------------------------------------------
    /// <summary>Object to obtain a lock on before updating the task counter.</summary>
    protected static  object          countLock           = null;
    /// <summary>The task counter which holds the number of tasks in process.</summary>
    protected static  int             tasksInProcess      = 0;
    /// <summary>A WaitHandle which blocks while there are tasks in process and unblocks when all tasks are done.</summary>
    protected static  EventWaitHandle whileRunningBlocker = null;

    //-----------------------------------------------------------------------
    // CONSTRUCTORS
    //-----------------------------------------------------------------------
    static ParallelTaskManager()
    {
      //create a waithandle
      whileRunningBlocker = new EventWaitHandle(false, EventResetMode.ManualReset);

      //create lock object
      countLock = new Object();
    }

    //-----------------------------------------------------------------------
    // METHODS
    //-----------------------------------------------------------------------
    /// <summary>Increments the task counter which counts the number of tasks in process.</summary>
    protected static void incrementTaskCounter()
    {
      //count the number of concurring tasks
      lock (countLock)
      {
        //count the number of concurring tasks
        tasksInProcess++;

        //set to block when there are tasks running
        if (tasksInProcess == 1)
          whileRunningBlocker.Reset();
      }
    }

    //-----------------------------------------------------------------------
    /// <summary>Decrements the task counter which counts the number of tasks in process.</summary>
    protected static void decrementTaskCounter()
    {
      lock (countLock)
      {
        //count the number of concurring tasks
        tasksInProcess--;

        //unblock when all tasks are done
        if (tasksInProcess == 0)
          whileRunningBlocker.Set();
      }
    }

    //-----------------------------------------------------------------------
    /// <summary>Blocks the current thread while there are still tasks in process. It releases (unblocks) when all tasks are done.</summary>
    /// <remarks>This base class maintains only one task-counter for all descendant classes. This means that this method blocks until all running tasks from all descendant classes have finished.</remarks>
    public static void blockWhileTasksRunning()
    {
      //block until all tasks are done
      whileRunningBlocker.WaitOne();
    }
    
    //-----------------------------------------------------------------------
    /// <summary>Returns the total number of tasks in progress. There is only one counter for all descendant classes. So this counter counts all running tasks.</summary>
    /// <remarks>This base class maintains only one task-counter for all descendant classes. This means that all running tasks from all descendant classes are counted here.</remarks>
    /// <returns>Returns the number of tasks that are either running or are still queued.</returns>
    public static int getRunningTasksCount()
    {
      return tasksInProcess;
    }
    
    //-----------------------------------------------------------------------
  }
}
